grammar Flex;

options {
  language = Java;
  output = AST;
  //backtrack = true;
  //memoize = true;
  k = 7;
}

@lexer::header {
   package flexgram;
}

@header {
   package flexgram;
}
fragment
CAR : ('a'..'z'|'A'..'Z'|'0'..'9'|' '|'%'|'='|'\\') ;

STR     : '"' CAR* '"';

ID  : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
    ;

INT : '0'..'9'+
    ;

FLOAT
    :   ('0'..'9')+ '.' ('0'..'9')* EXPONENT?
    |   '.' ('0'..'9')+ EXPONENT?
    |   ('0'..'9')+ EXPONENT
    ;

COMMENT
    :   '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
    |   '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
    ;

SPACE
    :   ( ' '
        | '\t'
        )+ 
    ;



    
CJTOCAR
    : '[' RANGO+ ']'
    ;
    
fragment
RANGO
      : CAR '-' CAR
      ;     

IND   : '[' INT ']' ;



STRING :  '"' ( ESC_SEQ | ~('\\'|'"') )* '"'
    ;

CHAR:  '\'' ( ESC_SEQ | ~('\''|'\\') ) '\''
    ;

fragment
EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;

fragment
HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;

fragment
ESC_SEQ
    :   '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
    |   UNICODE_ESC
    |   OCTAL_ESC
    ;

fragment
OCTAL_ESC
    :   '\\' ('0'..'3') ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7')
    ;

fragment
UNICODE_ESC
    :   '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
    ;
    
NEWLINE :'\r'? '\n' ;

SECCION : '%%' NEWLINE;
   
BLOQOP: '%{' NEWLINE ;

BLOQCL: '%}' NEWLINE ;

SEMI  : ';' ;

REF   : '{' ID '}' ;

LLAVOP  : '{';
LLAVCL  : '}';

COMA    : ',';

EQ      : '=';

PAROP   : '(';
PARCL   : ')';
COROP   : '[';
CORCL   : ']';
OR      : '|';

ASTER    :  '*';
PLUS     
  : '+';

OPINC    :      '++' ;  

//bloque: BLOQOP .* BLOQCL ;
bloque: BLOQOP (options {greedy=false;}:.)* BLOQCL;

fichero : definiciones (bloque)? SECCION reglas (SECCION codigo)?;

definiciones : (definicion)+;

definicion : name valor;

name : ID;

valor: SPACE (options {greedy=false;}:.)* NEWLINE;

reglas: (regla)+;

regla: patron accion;

patron: ~SECCION (options {greedy=false;}:.)* SPACE;

accion: (options {greedy=false;}:.)* NEWLINE;

codigo: (options {greedy=false;}:.)* EOF;
